function Promise(executor) {
    let self = this;
    this.promiseState = 'pending';
    this.promiseResult = null;
    this.callbacks = [];
    function resolve(value) {
        if (self.promiseState !== 'pending') return;
        self.promiseState = 'fulfilled';
        self.promiseResult = value;
        self.callbacks.forEach(callback => {
            callback.onResolve(value);
        })
    }
    function reject(reason) {
        if (self.promiseState !== 'pending') return;
        self.promiseState = 'rejected';
        self.promiseResult = reason;
        self.callbacks.forEach(callback => {
            callback.onReject(reason);
        })
    }
    try {
        executor(resolve, reject);
    } catch (e) {
        reject(e);
    }
}

Promise.prototype.then = function (onResolve, onReject) {
    return new Promise((resolve, reject) => {
        if(typeof onReject != 'function'){
            onReject = reason =>{
                throw reason;
            }
        }
        if(typeof onResolve != 'function'){
            onResolve = v=>v;
        }
        let changeState = (type)=>{
            try{
                let rs = type(this.promiseResult);
                if(rs instanceof Promise){
                    rs.then(resolve, reject);
                }else{
                    resolve(rs);
                }
            }catch(e){
                reject(e);
            }
        }
        if (this.promiseState === 'fulfilled') {
            changeState(onResolve);
        }
        if (this.promiseState === 'rejected') {
            changeState(onReject)
        }
        if (this.promiseState === 'pending') {
            this.callbacks.push({
                onReject: () => {
                    changeState(onReject)
                },
                onResolve: () => {
                    changeState(onResolve);
                }
            })
        }
    })
}

Promise.prototype.catch = function(onRejected){
    return this.then(null,onRejected);
}

